
package com.mengshu.security.filter;

import com.mengshu.security.handler.IParamsSignHandler;
import com.mengshu.security.properties.SecurityProperties;
import org.springframework.core.Ordered;
import org.springframework.http.HttpMethod;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 请求参数签名过滤器
 */
public class ParamsSignRequestFilter extends OncePerRequestFilter implements Ordered {

    private IParamsSignHandler paramsSignHandler;

    private Set<String> excludes = new HashSet<>();

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    public ParamsSignRequestFilter(SecurityProperties securityProperties, IParamsSignHandler paramsSignHandler) {
        this.paramsSignHandler = paramsSignHandler;
        if (StringUtils.hasText(securityProperties.getExcludes())) {
            this.excludes = Arrays.stream(securityProperties.getExcludes().split(","))
                    .filter(p -> StringUtils.hasText(p)).collect(Collectors.toSet());
        }
    }

    @Override
    public int getOrder() {
        return LOWEST_PRECEDENCE - 6;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String servletPath = request.getServletPath();
        if (excludes.stream().anyMatch(pattern -> antPathMatcher.match(pattern, servletPath))) {
            filterChain.doFilter(request, response);
        } else {
            // 请求参数验签
            ParamsSignRequestWrapper signRequest = new ParamsSignRequestWrapper(request);
            if (Objects.equals(HttpMethod.GET.name(), signRequest.getMethod())) {
                paramsSignHandler.doGet(signRequest);
            } else if (signRequest.getContentType().contains("application/json")) {
                // 请求body内容处理
                paramsSignHandler.doPost(signRequest);
            }
            filterChain.doFilter(signRequest, response);
        }
    }

}
